﻿// License Notification
//======================================================
// Copyright (c) 2010 Channel Intelligence Inc.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// ======================================================




using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml.Linq;
using Castle.Core.Resource;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using CIP4.Common;
using CIP4.Simple;
using MassTransit;
using MassTransit.Transports.Msmq;
using MassTransit.WindsorIntegration;

namespace CIP4.DataProvider.MassTransit
{
    /// <summary>
    /// The dll client uses this by instantiating an instance of RequestMessageReceiver
    /// The class instance will stop consuming events when the instance is disposed of
    /// </summary>
    public class RequestMessageReceiver: IDisposable
    {
        private readonly string _busId;

        private readonly IServiceBus _bus;
        private readonly RequestMessageConsumer _consumer;
        private readonly IWindsorContainer _container;
        public static LoggerDelegate Logger;

        public static Assembly ItemTypesAssembly;

        public static Dictionary<string, CIP4ConnectionAttribute> Connections = new Dictionary<string,CIP4ConnectionAttribute>();

        public RequestMessageReceiver(string busId, LoggerDelegate logger, Assembly itemTypesAssembly, Dictionary<string, CIP4ConnectionAttribute> connections)
        {
            Connections = connections;

            ItemTypesAssembly = itemTypesAssembly;

            Globals.AddAssemblyPath(Path.GetDirectoryName(itemTypesAssembly.Location), logger);

            _busId = busId;

            Logger = logger;

            _container = BootstrapContainer();

            _bus = _container.Resolve<IServiceBus>();
            
            _consumer = _container.Resolve<RequestMessageConsumer>();

            _consumer.Start(_bus, itemTypesAssembly, connections);
            
        }

        private IWindsorContainer BootstrapContainer()
        {
            MsmqEndpointConfigurator.Defaults(x => { x.CreateMissingQueues = true; });

            string windsorText = WindsorMaker.GetWindsorXml(_busId, "server");

            Logger(MajorEnum.Trace, MinorEnum.Generic, "Windsor text={0}",
                   new object[] {XElement.Parse(windsorText).ToString()});

            StaticContentResource scr = new StaticContentResource(windsorText);

            XmlInterpreter xi = new XmlInterpreter(scr);

            IWindsorContainer container = new DefaultMassTransitContainer(xi);

            container.Register(Component.For<RequestMessageConsumer>().LifeStyle.Transient);
            
            return container;
        }

        #region IDisposable Members

        public void Dispose()
        {
            _consumer.Stop();
            _consumer.Dispose();
            _container.Release(_bus);
            _container.Dispose();
        }

        #endregion
    }
}
